/*
 * XMLMapLoader.java
 *
 * Copyright (C) 2012 Matt Falkoski
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.falko.android.pinhead;

import java.io.IOException;
import java.io.InputStream;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.util.Log;
import android.util.Xml;

/**
 * @author matt
 * 
 */
public class XMLMapLoader implements MapLoader {

	public XMLMapLoader() {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.falko.android.pinhead.MapLoader#loadMap(java.io.InputStream,
	 * android.content.Context)
	 */
	public TestMap loadMap(InputStream in, Context c) {
		map = null;
		context_ = c;
		try {
			XmlPullParser parser = Xml.newPullParser();
			parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
			parser.setInput(in, null);
			map = parseXML(parser);
		} catch (XmlPullParserException e) {
			Log.v("pinhead", e.getMessage());
		} catch (IOException e) {
			Log.v("pinhead", e.getMessage());
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				// stuff happens
			}
		}
		assert map != null;
		return map;
	}

	private TestMap parseXML(XmlPullParser parser)
			throws XmlPullParserException, IOException {

		map = new TestMap();
		while (parser.next() != XmlPullParser.END_DOCUMENT) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
			String tagName = parser.getName();

			if (tagName.equals("map")) {
				
				parseMap(parser);
				
			} else if (tagName.equals("tileset")) {
				
				parseTileSet(parser);
				
			} else if (tagName.equals("image")) {
				
				parseImage(parser);
				
			} else if (tagName.equals("layer")) {
				
				parseLayer(parser);

			} else if (tagName.equals("data")) {
				
				parseData(parser);
			}
		}
		return map;
	}

	private void parseMap(XmlPullParser parser) {
		
		String attributeName = "";
		int ac = parser.getAttributeCount();
		for (int i = 0; i < ac; ++i) {
			attributeName = parser.getAttributeName(i);
			if (attributeName.equals("width")) {
				map.mapWidth_ = Integer.parseInt(parser
						.getAttributeValue(i));
			} else if (attributeName.equals("height")) {
				map.mapHeight_ = Integer.parseInt(parser
						.getAttributeValue(i));
			}
		}
		map.mapData_ = new long[map.mapHeight_][map.mapWidth_];
	}

	private void parseTileSet(XmlPullParser parser) {
		
		String attributeName = "";
		int ac = parser.getAttributeCount();
		for (int i = 0; i < ac; ++i) {
			attributeName = parser.getAttributeName(i);
			if (attributeName.equals("name")) {
				map.tileSet_.texture_.resource = Utils.getResId(
						parser.getAttributeValue(i), context_,
						R.drawable.class);
				Log.v("pinhead", "resource:  "
						+ map.tileSet_.texture_.resource);
			} else if (attributeName.equals("tilewidth")) {
				map.tileSet_.tileWidth_ = Integer.parseInt(parser
						.getAttributeValue(i));
			} else if (attributeName.equals("tileheight")) {
				map.tileSet_.tileHeight_ = Integer.parseInt(parser
						.getAttributeValue(i));
			}
		}
	}
	
	private void parseImage(XmlPullParser parser) {

		String attributeName = "";
		int ac = parser.getAttributeCount();
		for (int i = 0; i < ac; ++i) {
			attributeName = parser.getAttributeName(i);
			if (attributeName.equals("width")) {
				map.tileSet_.width_ = Integer.parseInt(parser
						.getAttributeValue(i))
						/ map.tileSet_.tileWidth_;
			} else if (attributeName.equals("height")) {
				map.tileSet_.height_ = Integer.parseInt(parser
						.getAttributeValue(i))
						/ map.tileSet_.tileHeight_;
			}
		}
	}
	
	private void parseLayer(XmlPullParser parser) {

	}
	
	private void parseData(XmlPullParser parser) throws XmlPullParserException, IOException {
		if (parser.next() != XmlPullParser.TEXT) {
			map = null;
			throw new IOException("No Tile Data");
		}

		String mapDataStr = parser.getText();
		String[] mapStrArray = mapDataStr.split(",");

		for (int tileY = map.mapHeight_ - 1; tileY >= 0; tileY--) {
			for (int tileX = 0; tileX < map.mapWidth_; tileX++) {
				final int y = map.mapHeight_ - tileY - 1;
				map.mapData_[tileY][tileX] = Long
						.parseLong(mapStrArray[y * map.mapWidth_
								+ tileX].trim());
			}
		}
	}

	
	private Context context_;
	private TestMap map;
}
